<?php
/**
 * Description of DbMapper
 *
 * @author Thomas Breuss
 */
abstract class WSB_DbMapper
{

    /**
     * @var Zend_Db_Adapter
     */
    protected $_dbAdapter;

    /**
     * @var Zend_Db_Select
     */
    protected $_dbSelect;

    /**
     * @var string
     */
    protected $_collectionClass = 'WSB_Collection2';

    /**
     * @var string
     */
    protected $_modelClass = 'WSB_Model2';

    protected $_useTimeFields = true;
    
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->_dbAdapter = Zend_Db_Table_Abstract::getDefaultAdapter();

        $config = $GLOBALS['WSB']['mappers'][get_class($this)];
        $this->_collectionClass = $config['collectionClass'];
        $this->_modelClass = $config['modelClass'];
        $this->_filterSql = $config['filterSql'];

        $this->init();
    }

    public function init()
    {
    }

    public function setCollectionClass($className)
    {
        $this->_collectionClass = $className;
    }

    public function getCollectionClass()
    {
        return $this->_collectionClass;
    }

    public function setModelClass($className)
    {
        $this->_modelClass = $className;
    }

    public function getModelClass()
    {
        return $this->_modelClass;
    }

    public function setUseTimeFields($flag)
    {
        $this->_useTimeFields = (bool)$flag;
    }

    public function getUseTimeFields()
    {
        return $this->_useTimeFields;
    }

    public function getAdapter()
    {
        return $this->_dbAdapter;
    }

    public function getSelect()
    {
        return $this->_dbAdapter->select();
    }

    public function getPaginator($pageNumber=1, $ordering='', $filter='')
    {
        $select = $this->_selectAll();
        $select->order($ordering);

        if(!empty($filter) && !empty($this->_filterSql)) {
            $select->where($this->_filterSql, '%' . $filter . '%');
            // $query->where("MATCH (`desc`,`keyword`) AGAINST (\"$find\")"); 
        }

        $adapter = new Zend_Paginator_Adapter_DbSelect($select);
        $paginator = new Zend_Paginator($adapter);
        $paginator->setItemCountPerPage(20);
        $paginator->setCurrentPageNumber($pageNumber);
        return $paginator;
    }

    public function fetchAll()
    {
        $select = $this->_selectAll();
        $stmt = $this->_dbAdapter->query($select);
        $result = $stmt->fetchAll();
        return new $this->_collectionClass($result);
    }

    public function find($id)
    {
        $select = $this->_selectFind($id);
        $stmt = $this->_dbAdapter->query($select);
        $result = $stmt->fetch();
        if(!empty($result)) {
            return new $this->_modelClass($result);            
        }
    }

    public function save(WSB_Model2 $model)
    {
        $id = $this->_save($model);
        $model->id = $id;
    }

    abstract protected function _save(WSB_Model2 $model);
    
    abstract protected function _selectAll();

    abstract protected function _selectFind($id);
    
    /**
     *
     * @param string $table
     * @param array $data
     * @return integer Last insert ID
     */
    protected function _insert($table, $data)
    {
        if($this->_useTimeFields) {
            $data['created'] = time();
            unset($data['modified']);
        }
        $this->_dbAdapter->insert($table, $data);
        return $this->_dbAdapter->lastInsertId($table);
    }

    /**
     * @param string $table
     * @param array $multiData
     * @param array $override
     * @return array
     */
    protected function _multiInsert($table, $multiData, $override)
    {
        $insertIds = array();
        foreach($multiData AS $data) {            
            $insertIds[] = $this->_insert($table, array_merge($data, $override));
        }
        return $insertIds;
    }

    /**
     * @param string $tabel
     * @param array $data
     * @param integer $id
     * @return integer Number of affected rows
     */
    protected function _update($table, $data, $id)
    {
        if($this->_useTimeFields) {
            $data['modified'] = time();
            unset($data['created']);
        }
        $where = $this->_dbAdapter->quoteInto('id=?', $id);
        return $this->_dbAdapter->update($table, $data, $where);
    }

    /**
     * @param string $table
     * @param string $where
     * @return integer Number of affected rows
     */
    protected function _delete($table, $where)
    {
        return $this->_dbAdapter->delete($table, $where);
    }
    
}
